#include "TcpClient.h"
#include "Hp4067Mux.h"

// ------------------- 1. 高频配置（60次/秒 = 间隔16.7ms，取16ms） -------------------
const char* WIFI_SSID = "时间赶马";
const char* WIFI_PWD = "Sj5688888";
const char* SERVER_IP = "192.168.31.35";
const uint16_t SERVER_PORT = 8888;

const uint8_t TOTAL_CHANNELS = 16;
const unsigned long READ_INTERVAL = 8;    // 读取间隔8ms（125次/秒，超采样提高精度）
const unsigned long SEND_INTERVAL = 16;   // 发送间隔16ms（62.5次/秒，接近60次/秒）
const uint16_t MIN_POT_VALUE = 1200;
const uint16_t DATA_CHANGE_THRESHOLD = 1; // 数据变化阈值1（高频下允许更小波动）

// ------------------- 2. 实例与全局变量 -------------------
TcpClient tcpClient(WIFI_SSID, WIFI_PWD, SERVER_IP, SERVER_PORT);
Hp4067Mux mux;

uint16_t potValues[TOTAL_CHANNELS];      // 当前电位器值
uint16_t lastSentValues[TOTAL_CHANNELS]; // 上次发送值（数据去重）
unsigned long lastReadTime = 0;
unsigned long lastSendTime = 0;

// ------------------- 3. 初始化 -------------------
void setup() {
  Serial.begin(115200);
  while (!Serial);

  mux.begin();
  tcpClient.begin();

  // 添加网络信息打印（放在WiFi连接成功后）
  Serial.println("=== 网络信息 ===");
  Serial.print("ESP32 IP 地址: ");
  Serial.println(WiFi.localIP());
  Serial.print("网关地址: ");
  Serial.println(WiFi.gatewayIP());
  Serial.print("子网掩码: ");
  Serial.println(WiFi.subnetMask());

  Serial.println("=== 高频模式初始化完成（目标60次/秒） ===");

  // 初始化当前值和上次发送值（避免首次发送异常）
  for (uint8_t i = 0; i < TOTAL_CHANNELS; i++) {
    potValues[i] = MIN_POT_VALUE;
    lastSentValues[i] = MIN_POT_VALUE;
  }
}

// ------------------- 4. 主循环（精准计时，减少阻塞） -------------------
void loop() {
  tcpClient.loop(); // 维持TCP连接（内部无长阻塞）

  // 1. 高频读取（8ms/次）：超采样确保数据连续性
  if (millis() - lastReadTime >= READ_INTERVAL) {
    lastReadTime = millis();
    readAllPotentiometers();
  }

  // 2. 精准高频发送（16ms/次）：先更新时间戳，避免重复触发
  if (millis() - lastSendTime >= SEND_INTERVAL && tcpClient.isConnected()) {
    lastSendTime = millis(); // 关键：先占时，再处理，避免高频下多次进入
    if (isDataChanged()) {   // 只发送变化的数据，减少无效传输
      sendPotentiometerData();
    }
  }
}

// ------------------- 5. 读取电位器（优化通道切换速度） -------------------
void readAllPotentiometers() {
  for (uint8_t channel = 0; channel < TOTAL_CHANNELS; channel++) {
    // 读取通道（复用Hp4067Mux的readChannel，内部已优化延迟）
    uint16_t rawValue = mux.readChannel(channel);
    // 数据处理：过滤低于阈值的干扰
    potValues[channel] = (rawValue < MIN_POT_VALUE) ? MIN_POT_VALUE : rawValue;
  }
}

// ------------------- 6. 数据去重（高频下必须保留，减少树莓派压力） -------------------
bool isDataChanged() {
  for (uint8_t i = 0; i < TOTAL_CHANNELS; i++) {
    if (abs(potValues[i] - lastSentValues[i]) > DATA_CHANGE_THRESHOLD) {
      return true; // 任一通道变化则发送
    }
  }
  return false; // 无变化则不发送
}

// ------------------- 7. 发送数据（减少串口打印，避免阻塞） -------------------
void sendPotentiometerData() {
  bool sendSuccess = tcpClient.sendMultiplePotentiometerData(potValues);
  if (sendSuccess) {
    // 更新上次发送值，用于下次去重
    for (uint8_t i = 0; i < TOTAL_CHANNELS; i++) {
      lastSentValues[i] = potValues[i];
    }
    // 【关键】高频下关闭串口打印，或仅每10次打印1次（避免阻塞）
    #if 0 // 0=关闭打印，1=开启（调试时用）
      static uint8_t printCount = 0;
      if (++printCount >= 10) {
        printCount = 0;
        Serial.print("[");
        Serial.print(millis());
        Serial.println("] 高频发送成功");
      }
    #endif
  }
}